package com.ztsoft.user.utils;

/**
 * 密码处理工具
 */
public class PassWordUtils {

    private PassWordUtils() {
    }

    /**
     * 密码是否是正序或反序连续4位及以上
     *
     * @param pwd 需检验的密码
     * @return true为正确，false为错误。
     */
    public static boolean isPasswordContinuous(String pwd) {
        //正序次数
        int count = 0;
        //反序次数
        int reverseCount = 0;
        String[] strArr = pwd.split("");
        //从1开始是因为划分数组时，第一个为空
        for (int i = 1; i < strArr.length - 1; ++i) {
            if (isPositiveContinuous(strArr[i], strArr[i + 1])) {
                count++;
            } else {
                count = 0;
            }
            if (isReverseContinuous(strArr[i], strArr[i + 1])) {
                reverseCount++;
            } else {
                reverseCount = 0;
            }
            if (count > 2 || reverseCount > 2) break;
        }
        return count <= 2 && reverseCount <= 2;
    }

    /**
     * 是否是正序连续
     *
     * @param str1
     * @param str2
     * @return
     */
    public static boolean isPositiveContinuous(String str1, String str2) {
        return str2.hashCode() - str1.hashCode() == 1;
    }

    /**
     * 是否是反序连续
     *
     * @param str1
     * @param str2
     * @return
     */
    public static boolean isReverseContinuous(String str1, String str2) {
        return str2.hashCode() - str1.hashCode() == -1;
    }

    /**
     * 验证密码是否存在多个连续重复的字符， 如！！！！, qqqq, 1111, ====, AAAA
     *
     * @param password    字符串
     * @param repetitions 重复次数
     * @return false：不重复
     */
    public static boolean checkSequentialSameChars(String password, int repetitions) {
        int n = password.length();
        char[] pwdCharArr = password.toCharArray();
        int count;
        for (int i = 0; i + repetitions <= n; ++i) {
            count = 0;
            for (int j = 0; j < repetitions - 1; ++j) {
                if (pwdCharArr[i + j] == pwdCharArr[i + j + 1]) {
                    count++;
                    if (count == repetitions - 1) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * - 字母区分大小写，可输入符号
     * - 密码必须同时包含大写字母、小写字母、特殊符号和数字
     * - 密码长度8-20位
     * - 密码中不能存在连续4个及以上的数字或字母（如：1234、7654、abcd、defgh等）
     * - 验证密码是否存在4个及以上连续重复的字符， 如！！！！, qqqq, 1111, ====, AAAA
     *
     * @param password 密码
     * @return true为正确，false为错误
     */
    public static boolean isPasswordAvailable(String password) {
        //必须同时包含字母数字并且是8-20位，字符需要哪些可以调整正则，不可能无限支持所有的字符，一般都是指定部分字符
        String str = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[$@$!%*?&])[A-Za-z\\d$@$!%*?&]{8,20}";
        if (password.matches(str) && !checkSequentialSameChars(password, 4)) {
            return isPasswordContinuous(password);
        }
        return false;
    }

}